package com.ld.security.auth.shiro.websocket;

import lombok.extern.slf4j.Slf4j;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


@Slf4j
public abstract class AbstWebSocketServer {

    protected  static Map<String,Map<String,AbstWebSocketServer>> glMap = new ConcurrentHashMap();

    Map sessionMap = this.getTopic();

    protected Session session;

    //接收sid
    protected String sid;
    /**
     * 连接建立成功调用的方法*/
    @OnOpen
    public void onOpen(Session session,@PathParam("sid") String sid) {

        this.session = session;
        this.sid=sid;
        sessionMap.put(sid,this);
        log.info("连接成功:"+sid);
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {

        try{
            if(this.session.isOpen()){
                this.session.close();
            }

        } catch (Exception e){
            e.printStackTrace();
        }
        finally{
            sessionMap.remove(this.sid);

        }


        log.info("连接关闭:"+sid);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("收到来自窗口"+sid+"的信息:"+message);

            this.sendMessage(message);


    }

    /**
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误,连接关闭");
        this.onClose();
        error.printStackTrace();
    }
    /**
     * 指定用户消息推送
     */
    public void sendMessage(String message)  {
        try{
            this.session.getBasicRemote().sendText(message);
        }catch (Exception e){
            e.printStackTrace();
            this.onClose();
        }

    }

    public <E extends AbstWebSocketServer> E get(String id){

        return (E)sessionMap.get(id);
    }


    private   Map<String,AbstWebSocketServer> getTopic(){
        ServerEndpoint serverEndpoint = this.getClass().getAnnotation(ServerEndpoint.class);
        String key = serverEndpoint.value();
        Map<String,AbstWebSocketServer> sessionMap =      glMap.get(key);
        if(sessionMap == null){
            sessionMap =new ConcurrentHashMap();
            glMap.put(key,sessionMap);
        }
        return sessionMap;
    }

}
